package com.doudou.zuul.utils;

import com.alibaba.fastjson.JSON;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
import java.util.Map;

public class TokenUtils {

    /**
     * 黑名单前缀
     */
    public static final String ACCESS_TOKEN_BLACK_LIST_PREFIX = "ACC_BLACK:";
    public static final String REFRESH_TOKEN_BLACK_LIST_PREFIX = "REF_BLACK:";
    /**
     * 刷新token前缀
     */
    public static final String REFRESH_TOKEN_KEY_PREFIX = "REFRESH_TOKEN_PREFIX:";


    public static final int BLACK_LIST_TIME = 60 * 60 * 24;


    public static final int REFRESH_TOKEN_CACHE_TIME = (60 - 5) * 60;


    /**
     * 提取载荷
     *
     * @param token
     * @return
     */
    public static Map<String, String> extractPlayLoad(String token) {
        String[] sp = token.split("\\.");
        if (sp == null || sp.length != 3 || StringUtils.isEmpty(sp[1])) {
            throw new RuntimeException("传入的token格式不对！");
        }
        Map<String, String> map = JSON.parseObject(new String(Base64.getDecoder().decode(sp[1])), Map.class);
        if (map == null || map.size() == 0) {
            throw new RuntimeException("传入的token非法！");
        }
        return map;
    }

    /**
     * 提取jti
     *
     * @param playLoad
     * @return
     */
    public static String extractJti(Map<String, String> playLoad) {
        return playLoad.get("jti");
    }


    /**
     * request 中提取acess_token
     *
     * @param request
     * @return
     */
    public static String extractAccessToken(HttpServletRequest request) {

        //允许返回null值
        String authorization = request.getHeader("Authorization");
        if (StringUtils.isEmpty(authorization)) {
            return null;
        }
        //校验格式
        if (!authorization.startsWith("bearer ")) {
            throw new RuntimeException("传入的鉴权参数Authorization格式不正确！");
        }
        String[] sp = authorization.split(" ");
        if (sp == null && sp.length != 2) {
            throw new RuntimeException("传入的鉴权参数Authorization格式不正确！");
        }
        String accessToken = sp[1];
        if (StringUtils.isEmpty(accessToken)) {
            throw new RuntimeException("传入的鉴权参数token解析为空！");
        }
        return accessToken;
    }

    public static String extractBlackListTokenKey(Map playLoad) {
        String jti = extractJti(playLoad);
        String key = ACCESS_TOKEN_BLACK_LIST_PREFIX + jti;
        return key;
    }


    public static String extractRefreshTokenKey(Map playLoad) {
        String jti = extractJti(playLoad);
        String key = REFRESH_TOKEN_KEY_PREFIX + jti;
        return key;
    }

    public static String extractRefreshTokenKey(String accessToken) {
        Map<String, String> playLoad = extractPlayLoad(accessToken);
        String jti = extractJti(playLoad);
        String key = REFRESH_TOKEN_KEY_PREFIX + jti;
        return key;
    }

    public static String extractBlackListRefreshTokenKey(Map playLoad) {
        String jti = extractJti(playLoad);
        String key = REFRESH_TOKEN_BLACK_LIST_PREFIX + jti;
        return key;
    }

}
